package com.xbongbong.paas.help.menu;

import com.xbongbong.admin.pojo.dto.MirrorRollBackDTO;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasAppEntity;
import com.xbongbong.paas.domain.entity.PaasFormEntity;
import com.xbongbong.paas.domain.entity.PaasMenuEntity;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.EnableEnum;
import com.xbongbong.paas.service.init.AbstractInitMenuHelp;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.model.PaasMenuModel;
import com.xbongbong.paas.pojo.dto.MenuFormAddDTO;
import com.xbongbong.paas.pojo.dto.MenuGroupAddDTO;
import com.xbongbong.paas.service.PaasMenuService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.pro.enums.AccessLinkEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.menu.enums.BundleMenuEnum;
import com.xbongbong.pro.enums.menu.enums.JXCMenuEnum;
import com.xbongbong.pro.enums.menu.enums.SystemAppMenuEnum;
import com.xbongbong.pro.menu.pojo.dto.MenuFormAddBatchDTO;
import com.xbongbong.pro.menu.pojo.dto.MenuGroupAddBatchDTO;
import com.xbongbong.pro.menu.pojo.dto.MenuInitDTO;
import com.xbongbong.pro.menu.pojo.vo.MenuFormAddBatchVO;
import com.xbongbong.pro.menu.pojo.vo.MenuGroupAddBatchVO;
import com.xbongbong.pro.menu.pojo.vo.MenuInitVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 *
 * @author 吴峰
 * @version v1.0
 * @date 2019/1/17 19:46
 * @since v1.0crm应用生成和菜单初始化
 */
@Component
public class InitBundleMenuHelp extends AbstractInitMenuHelp {

    private static final Logger LOG = LoggerFactory.getLogger(InitBundleMenuHelp.class);

    @Resource
    private PaasMenuService paasMenuService;
    @Resource
    private PaasMenuModel paasMenuModel;
    @Resource
    private PaasFormModel paasFormModel;

    @Override
    public List<String> alias() {
        return Arrays.asList(SystemAppMenuEnum.BUNDLE.getAlias());
    }

    @Override
    public MenuInitVO initApp(MenuInitDTO menuInitDTO, Map<String, PaasAppEntity> appMap) throws XbbException {
        return initMenu(menuInitDTO, appMap);
    }

    /**
     * 钉钉群菜单初始化
     * @author chenshan
     * @date 2020/9/18 18:44
     * @param menuInitDTO
     * @return void
     * @throws XbbException
     */
    @Override
    public MenuInitVO initMenu(MenuInitDTO menuInitDTO, Map<String, PaasAppEntity> appMap) throws XbbException {
        MenuInitVO menuInitVO = new MenuInitVO();
        try {
            // 获取下应用id
            Long appId = appMap.get(SystemAppMenuEnum.BUNDLE.getAlias()).getId();
            menuInitDTO.setAppId(appId);
            // 插入菜单分组
            MenuGroupAddBatchVO bundGroupAddBatchVO = groupAddBatch(menuInitDTO);
            if(Objects.isNull(bundGroupAddBatchVO)){
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }
            // 插入除分组外对应的菜单
            formAddBatch(menuInitDTO, bundGroupAddBatchVO);
        } catch (XbbException e){
            throw e;
        } catch (Exception e){
            LOG.error("InitCrmMenuHelp.menuInit初始化菜单出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return menuInitVO;
    }
    
    @Override
    public void rollBackInit(MirrorRollBackDTO mirrorRollBackDTO, List<Long> systemFormList, PaasFormEntity paasProductFormEntity) throws XbbException {
        String targetCorpid = mirrorRollBackDTO.getTargetCorpid();
        Long appId = mirrorRollBackDTO.getAppId();
        try {
            // 1. 回退菜单(根据安装的系统表单反推菜单)
            HashSet<Long> menuIds = new HashSet<>();
            HashMap<String,Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid", targetCorpid);
            param.put("appId", appId);
            param.put("idIn", systemFormList);
            param.put("del", DelEnum.NORMAL.getDel());
            List<PaasFormEntity> sysInstallFormList = paasFormModel.findEntity(param);
            sysInstallFormList.forEach(item -> {
                menuIds.add(item.getMenuId());
            });
            param.clear();
            param.put("corpid", targetCorpid);
            param.put("appId", appId);
            param.put("idIn", menuIds);
            param.put("del", DelEnum.NORMAL.getDel());
            List<PaasMenuEntity> paasMenuList = paasMenuModel.findEntitys(param);
            // 补充: 根据子菜单查父菜单
            HashSet<Long> parentMenuIds = new HashSet<>();
            paasMenuList.forEach(item -> {
                parentMenuIds.add(item.getParentId());
            });
            param.clear();
            param.put("corpid", targetCorpid);
            param.put("appId", appId);
            param.put("parentId", 0L);
            param.put("idIn", parentMenuIds);
            param.put("del", DelEnum.NORMAL.getDel());
            List<PaasMenuEntity> parentMenuList = paasMenuModel.findEntitys(param);
            paasMenuList.addAll(parentMenuList);
            updateInitMenu(paasMenuList, targetCorpid);
        } catch (XbbException e){
            throw e;
        } catch (Exception e){
            LOG.error("InitBundleMenuHelp.menuInit初始化菜单出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }
    
    private void updateInitMenu(List<PaasMenuEntity> paasMenuEntites, String corpid) throws XbbException {
        try {
            for (PaasMenuEntity paasMenuEntite : paasMenuEntites) {
                JXCMenuEnum menuEnum = JXCMenuEnum.getByAlias(paasMenuEntite.getAlias());
                paasMenuEntite.setName(menuEnum.getName());
                AccessLinkEnum accessLinkEnum = menuEnum.getAccessLinkEnum();
                paasMenuEntite.setIcon(accessLinkEnum.getIcon());
                paasMenuEntite.setEnable(EnableEnum.OPEN.getCode());
                paasMenuEntite.setColor(accessLinkEnum.getColor());
                paasMenuEntite.setUrl(accessLinkEnum.getUrl());
                paasMenuEntite.setType(menuEnum.getType());
                paasMenuEntite.setMobileUrl(accessLinkEnum.getMobileUrl());
            }
            paasMenuModel.updateBatch(paasMenuEntites,corpid);
        } catch (Exception e) {
            LOG.error("InitCrmMenuHelp.formExplainAddBatch批量修改菜单信息出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }
    
    /**
     * 批量添加分组
     * @author 吴峰
     * @date 2019/1/24 18:43
     * @param menuInitDTO
     * @return com.xbongbong.pro.menu.pojo.vo.MenuGroupAddBatchVO
     * @throws XbbException
     */
    private MenuGroupAddBatchVO groupAddBatch(MenuInitDTO menuInitDTO) throws XbbException {
        MenuGroupAddBatchVO menuGroupAddBatchVO;
        try {
            Long appId = menuInitDTO.getAppId();
            MenuGroupAddBatchDTO menuGroupAddBatchDTO = new MenuGroupAddBatchDTO();
            BeanUtil.copyProperties(menuInitDTO, menuGroupAddBatchDTO);
            menuGroupAddBatchDTO.setAppId(appId);
            List<MenuGroupAddDTO> groupMenuList = new ArrayList<>();
            for(BundleMenuEnum bundleMenuEnum: BundleMenuEnum.values()){
                if(StringUtil.isEmpty(bundleMenuEnum.getParent())){
                    MenuGroupAddDTO bundleMenuGroupAddDTO = new MenuGroupAddDTO();
                    BeanUtil.copyProperties(menuInitDTO, bundleMenuGroupAddDTO);
                    bundleMenuGroupAddDTO.setParentId(0L);
                    bundleMenuGroupAddDTO.setAppId(appId);
                    bundleMenuGroupAddDTO.setSaasMark(SaasMarkEnum.SAAS.getCode());
                    bundleMenuGroupAddDTO.setAlias(bundleMenuEnum.getAlias());
                    bundleMenuGroupAddDTO.setName(bundleMenuEnum.getName());
                    AccessLinkEnum accessLinkEnum = bundleMenuEnum.getAccessLinkEnum();
                    bundleMenuGroupAddDTO.setIcon(accessLinkEnum.getIcon());
                    bundleMenuGroupAddDTO.setColor(accessLinkEnum.getColor());
                    bundleMenuGroupAddDTO.setUrl(accessLinkEnum.getUrl());
                    bundleMenuGroupAddDTO.setMobileUrl(accessLinkEnum.getMobileUrl());
                    bundleMenuGroupAddDTO.setType(bundleMenuEnum.getType());
                    groupMenuList.add(bundleMenuGroupAddDTO);
                }
            }
            menuGroupAddBatchDTO.setMenuList(groupMenuList);
            menuGroupAddBatchVO = paasMenuService.addBatchGroupMenu(menuGroupAddBatchDTO);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("InitBundleMenuHelp.groupAddBatch批量添加分组出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return menuGroupAddBatchVO;
    }

    /**
     * 批量添加表单
     * @author chenshan
     * @date 2019/1/24 18:43
     * @param menuInitDTO
     * @param menuGroupAddBatchVO
     * @return com.xbongbong.pro.menu.pojo.vo.MenuFormAddBatchVO
     * @throws XbbException
     */
    private MenuFormAddBatchVO formAddBatch(MenuInitDTO menuInitDTO, MenuGroupAddBatchVO menuGroupAddBatchVO) throws XbbException {
        MenuFormAddBatchVO menuFormAddBatchVO;
        try {
            Long appId = menuInitDTO.getAppId();
            Map<String, PaasMenuEntity> menuMap = new HashMap<>(menuGroupAddBatchVO.getMenuList().size());
            menuGroupAddBatchVO.getMenuList().forEach((item)->{
                menuMap.put(item.getAlias(), item);
            });
            MenuFormAddBatchDTO bundleFormAddBatchDTO = new MenuFormAddBatchDTO();
            BeanUtil.copyProperties(menuInitDTO, bundleFormAddBatchDTO);
            bundleFormAddBatchDTO.setAppId(appId);
            List<MenuFormAddDTO> bundFormMenuList = new ArrayList<>();
            for(BundleMenuEnum bundleMenuEnum: BundleMenuEnum.values()){
                if(StringUtil.isEmpty(bundleMenuEnum.getParent())){
                    // 踢掉分组
                    continue;
                }
                MenuFormAddDTO menuFormAddDTO = new MenuFormAddDTO();
                BeanUtil.copyProperties(menuInitDTO, menuFormAddDTO);
                menuFormAddDTO.setAppId(appId);
                if(StringUtil.isEmpty(bundleMenuEnum.getParent())){
                    menuFormAddDTO.setParentId(0L);
                }else{
                    menuFormAddDTO.setParentId(menuMap.get(bundleMenuEnum.getParent()).getId());
                }
                menuFormAddDTO.setSaasMark(SaasMarkEnum.SAAS.getCode());
                menuFormAddDTO.setAlias(bundleMenuEnum.getAlias());
                menuFormAddDTO.setName(bundleMenuEnum.getName());
                AccessLinkEnum accessLinkEnum = bundleMenuEnum.getAccessLinkEnum();
                menuFormAddDTO.setIcon(accessLinkEnum.getIcon());
                menuFormAddDTO.setColor(accessLinkEnum.getColor());
                menuFormAddDTO.setUrl(accessLinkEnum.getUrl());
                menuFormAddDTO.setMobileUrl(accessLinkEnum.getMobileUrl());
                menuFormAddDTO.setType(bundleMenuEnum.getType());
                bundFormMenuList.add(menuFormAddDTO);
            }
            bundleFormAddBatchDTO.setMenuList(bundFormMenuList);
            menuFormAddBatchVO = paasMenuService.addBatchFormMenu(bundleFormAddBatchDTO);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("InitCrmMenuHelp.formAddBatch批量添加表单出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return menuFormAddBatchVO;
    }
}
